package com.wing.file.controller.admin;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.HexUtil;
import com.alibaba.fastjson.JSONObject;
import com.wing.common.annotation.LoginPass;
import com.wing.common.utils.JsonResult;
import com.wing.file.model.response.FileVO;
import com.wing.file.service.FileService;
import com.wing.web.annotation.AuthPass;
import com.wing.web.utils.LocaleMessage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.tika.Tika;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 *
 * @author
 */
@Api(value = "文件管理", tags = "文件管理")
@AuthPass
@CrossOrigin
@RestController
@RequestMapping("file/admin/file")
public class FileController {

    @Value("${wing.file.app.dir}")
    private String fileDir;
    @Value("${wing.file.app.uuidName}")
    private Boolean uuidName;
    @Value("${wing.file.app.useSm}")
    private Boolean useSm;
    @Value("${wing.file.app.useNginx}")
    private Boolean useNginx;
    @Value("${wing.file.app.nginxUrl}")
    private String nginxUrl;

    @Autowired
    private LocaleMessage localeMessage;
    @Autowired
    private FileService fileService;

    @ApiOperation(value = "上传文件")
    @ResponseBody
    @PostMapping("/upload")
    public JsonResult upload(@ApiParam(name = "attach",value = "attach", required = true) MultipartFile file) throws IOException {

        if (file == null || file.isEmpty()) {
            return JsonResult.fail("上传文件不能为空");
        }

        //文件类型检查
        String type = FileTypeUtil.getType(HexUtil.encodeHexStr(file.getBytes()));
        if(!type.equals("jpg") && !type.equals("png") && !type.equals("zip")){
            return JsonResult.exception("上传失败");
        }

        try{
            FileVO fileVO = fileService.saveImage(file);
            return JsonResult.success("上传成功", fileVO);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.exception("上传失败");
        }
    }

    // @PreAuthorize("hasAuthority('post:/file/admin/file/layuiUpload')")
    @ApiOperation(value = "layui富文本上传文件")
    @ResponseBody
    @PostMapping("/layuiUpload")
    public JsonResult layuiUpload(@ApiParam(name = "attach",value = "attach", required = true) MultipartFile file) throws IOException {

        if (file == null || file.isEmpty()) {
            return JsonResult.fail("上传文件不能为空");
        }

        //文件类型检查
        String type = FileTypeUtil.getType(HexUtil.encodeHexStr(file.getBytes()));
        if(!type.equals("jpg") && !type.equals("png")){
            return JsonResult.exception("上传失败");
        }

        try{
            FileVO fileVO = fileService.saveImage(file);

            if(fileVO == null){
                return JsonResult.exception("上传失败");
            }

            JSONObject data = new JSONObject();
            data.put("src", "file/get/" +fileVO.getUrl());
            data.put("smUrl", fileVO.getSmUrl());

            return JsonResult.success("上传成功", data);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.exception("上传失败");
        }
    }


    @ApiOperation(value = "查看原文件")
    @LoginPass
    @GetMapping(value = {"get/{y}/{m}/{d}/{file:.+}"})
    public String file(@PathVariable("y") String y, @PathVariable("m") String m, @PathVariable("d") String d, @PathVariable("file") String filename, HttpServletResponse response) {
        String filePath = y + "/" + m + "/" + d + "/" + filename;
        if (useNginx) {
            if (nginxUrl == null) {
                nginxUrl = "/";
            }
            if (!nginxUrl.endsWith("/")) {
                nginxUrl += "/";
            }
            String newName;
            try {
                newName = URLEncoder.encode(filePath, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                newName = filePath;
            }
            return "redirect:" + nginxUrl + newName;
        }
        if (fileDir == null) {
            fileDir = "/";
        }
        if (!fileDir.endsWith("/")) {
            fileDir += "/";
        }
        outputFile(fileDir + filePath, response);
        return null;
    }


    @ApiOperation(value = "查看缩略图")
    @LoginPass
    @GetMapping(value = {"get/sm/{y}/{m}/{d}/{file:.+}"})
    public String fileSm(@PathVariable("y") String y, @PathVariable("m") String m, @PathVariable("d") String d, @PathVariable("file") String filename, HttpServletResponse response) {
        String filePath = "sm/" + y + "/" + m + "/" + d + "/" + filename;
        if (useNginx) {
            if (nginxUrl == null) {
                nginxUrl = "/";
            }
            if (!nginxUrl.endsWith("/")) {
                nginxUrl += "/";
            }
            String newName;
            try {
                newName = URLEncoder.encode(filePath, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                newName = filePath;
            }
            return "redirect:" + nginxUrl + newName;
        }
        if (fileDir == null) {
            fileDir = "/";
        }
        if (!fileDir.endsWith("/")) {
            fileDir += "/";
        }
        outputFile(fileDir + filePath, response);
        return null;
    }


    @ApiOperation(value = "查看缓存原文件")
    @LoginPass
    @GetMapping(value = {"get/temp/{y}/{m}/{d}/{file:.+}"})
    public String fileTemp(@PathVariable("y") String y, @PathVariable("m") String m, @PathVariable("d") String d, @PathVariable("file") String filename, HttpServletResponse response) {
        //String filePath = "temp/" + y + "/" + m + "/" + d + "/" + filename;
        String filePath = y + "/" + m + "/" + d + "/" + filename;
        if (useNginx) {
            if (nginxUrl == null) {
                nginxUrl = "/";
            }
            if (!nginxUrl.endsWith("/")) {
                nginxUrl += "/";
            }
            String newName;
            try {
                newName = URLEncoder.encode(filePath, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                newName = filePath;
            }
            return "redirect:" + nginxUrl + newName;
        }
        if (fileDir == null) {
            fileDir = "/";
        }
        if (!fileDir.endsWith("/")) {
            fileDir += "/";
        }
        outputFile(fileDir + filePath, response);
        return null;
    }


    @ApiOperation(value = "查看缓存缩略图")
    @LoginPass
    @GetMapping(value = {"get/temp/sm/{y}/{m}/{d}/{file:.+}"})
    public String fileTempSm(@PathVariable("y") String y, @PathVariable("m") String m, @PathVariable("d") String d, @PathVariable("file") String filename, HttpServletResponse response) {
        String filePath = "temp/sm/" + y + "/" + m + "/" + d + "/" + filename;
        if (useNginx) {
            if (nginxUrl == null) {
                nginxUrl = "/";
            }
            if (!nginxUrl.endsWith("/")) {
                nginxUrl += "/";
            }
            String newName;
            try {
                newName = URLEncoder.encode(filePath, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                newName = filePath;
            }
            return "redirect:" + nginxUrl + newName;
        }
        if (fileDir == null) {
            fileDir = "/";
        }
        if (!fileDir.endsWith("/")) {
            fileDir += "/";
        }
        outputFile(fileDir + filePath, response);
        return null;
    }

    // 输出文件流
    private void outputFile(String file, HttpServletResponse response) {
        // 判断文件是否存在
        File inFile = new File(File.listRoots()[0], file);
        if (!inFile.exists()) {
            PrintWriter writer = null;
            try {
                response.setContentType("text/html;charset=UTF-8");
                writer = response.getWriter();
                writer.write("<!doctype html><title>404 Not Found</title><h1 style=\"text-align: center\">404 Not Found</h1><hr/><p style=\"text-align: center\">Easy File Server</p>");
                writer.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        // 获取文件类型
        String contentType = null;
        try {
            // Path path = Paths.get(inFile.getName());
            // contentType = Files.probeContentType(path);
            contentType = new Tika().detect(inFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (contentType != null) {
            response.setContentType(contentType);
        } else {
            response.setContentType("application/force-download");
            String newName;
            try {
                newName = URLEncoder.encode(inFile.getName(), "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                newName = inFile.getName();
            }
            response.setHeader("Content-Disposition", "attachment;fileName=" + newName);
        }
        // 输出文件流
        OutputStream os = null;
        FileInputStream is = null;
        try {
            is = new FileInputStream(inFile);
            os = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes, 0, len);
            }
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
